﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace frag_boardgame
{
    public class Line
    {
        double startX, startY, endX, endY;

        public Line (double startX, double startY, double endX, double endY)
        {

            this.startX = startX;
            this.startY = startY;
            this.endX = endX;
            this.endY = endY;

            if (startX > endX)
            {
                this.startX = endX;
                this.startY = endY;
                this.endX = startX;
                this.endY = startY;
            }

            if (startX == endX)
            {
                if (startY > endY)
                {
                    this.endY = startY;
                    this.startY = endY;
                }
            }
        }

        public double DY
        {
            get
            {
                return endY - startY;
            }
        }

        public double DX
        {
            get
            {
                return endX - startX;
            }
        }

        public double Deriv
        {
            get
            {
                if (DX == 0)
                    return double.NaN;
                return DY / DX;
            }
        }

        public double Offset
        {
            get
            {
                if (Deriv == double.NaN)
                    return double.NaN;
                return startY - (Deriv * startX);
            }
        }

        public double MinX
        {
            get
            {
                return Math.Min(startX, endX);
            }
        }
        public double MaxX
        {
            get
            {
                return Math.Max(startX, endX);
            }
        }
        public double MinY
        {
            get
            {
                return Math.Min(startY, endY);
            }
        }
        public double MaxY
        {
            get
            {
                return Math.Max(startY, endY);
            }
        }

        public double GetYofX(double x)
        {
            return Deriv * x + Offset;
        }

        public double GetXofY(double y)
        {
            if (Deriv == 0)
                return double.NaN;

            if (double.IsNaN(Deriv))
                return startX;
            
            return (y - Offset) / Deriv;
        }
        
        //internal use... it checks if (x,y) in the bounds of the square around the line...
        private bool inLineBounds (double x, double y) 
        {
            
            if ((this.MinX > x) || (this.MaxX < x) || (this.MinY > y) || (this.MaxY < y)) 
                return false;
            return true;
        }
        
        public static bool AreCrossing(Line line1, Line line2)
        {

            if (double.IsNaN(line1.Deriv) && double.IsNaN(line2.Deriv))
            {
                if ((line2.inLineBounds(line1.startX, line1.startY)) ||
                    (line1.inLineBounds(line2.startX, line2.startY)))
                    return true;
                return false;
            }
            
            double x, y;
            
            if (double.IsNaN(line1.Deriv))
            {
                x = line1.startX;
                y = line2.GetYofX(x);
            }

            else if (double.IsNaN(line2.Deriv))
            {
                x = line2.startX;
                y = line1.GetYofX(x);
            }

            else
            {
                x = (line2.Offset - line1.Offset) / (line1.Deriv - line2.Deriv);
                y = line1.Deriv * x + line1.Offset;
            }

            return (line1.inLineBounds(x,y) && line2.inLineBounds(x,y));
        }

    }
}
